package service

import (
	"context"
	"regexp"
	"sale-admin/config"
	"sale-admin/config/mysql"
	"sale-admin/config/redis"
	"sale-admin/internal/app/grpc/client"
	"sale-admin/internal/app/grpc/protoc/devicec"
	"sale-admin/internal/app/web/schema"
	"sale-admin/internal/app/web/service/common"
	"sale-admin/internal/app/web/service/pay"
	"sale-admin/internal/dao"
	"sale-admin/internal/define"
	"sale-admin/internal/models"
	"sale-admin/internal/pkg"
	"sale-admin/internal/pkg/points"
	"strconv"
	"strings"
	"time"

	"fmt"

	"192.168.1.75/go-pkg/errorx"
	"192.168.1.75/go-pkg/helper"
	"192.168.1.75/go-pkg/logx"
	"github.com/go-pay/gopay/wechat/v3"
	"github.com/samber/lo"
	"github.com/shopspring/decimal"
	miniOrder "github.com/silenceper/wechat/v2/miniprogram/order"
	"gorm.io/gorm"
)

type OrderPoints struct{}

type CartGoodsStruct struct {
	ID           int64   `json:"id"`
	ClassID      string  `json:"class_id"`
	GoodsName    string  `json:"goods_name"`
	ContainerNum string  `json:"container_num"`
	Univalent    float64 `json:"univalent"`
	RobotName    string  `json:"robot_name"`
	OrderGoodsInfo
}
type OrderGoodsInfo struct {
	GoodsID        string  `gorm:"column:goods_id" json:"goods_id"`               // 商品id
	GoodsType      int     `gorm:"column:goods_type" json:"goods_type"`           // 商品类型
	GoodsImage     string  `gorm:"column:goods_image" json:"goods_image"`         // 商品图片
	Points         float64 `gorm:"column:points" json:"points"`                   // 抵扣积分
	PointsSupport  int     `gorm:"column:points_support" json:"points_support"`   // 是否支持积分
	DeductionLimit float64 `gorm:"column:deduction_limit" json:"deduction_limit"` // 抵扣上限【元】
}

// 获取机器对接的积分系统信息
func (OrderPoints) GetRobotLocationInfo(ctx context.Context, db *gorm.DB, salesID string) (res *devicec.Location, err error) {
	// 机器信息
	RobotInfo, _ := dao.Robot{}.RobotDetail(ctx, db, "", "", salesID)
	if RobotInfo == nil || RobotInfo.ID == "" {
		err = errorx.New("机器信息不存在", -1)
		return
	}
	// 初始化GRPC
	deviceClient, clientErr := client.GetDeviceAdminClient()
	if clientErr != nil {
		logx.Error(context.Background(), "grpc device client error", logx.Err(clientErr))
		err = errorx.New("系统错误", -1)
		return
	}

	// GRPC获取商场位置列表
	deviceReq := &devicec.LocationDetailReq{}
	deviceReq.LocationId = strconv.Itoa(RobotInfo.Areas3)
	deviceRes, err := deviceClient.LocationDetail(context.Background(), deviceReq)
	if deviceRes != nil && deviceRes.Code == 0 && err == nil {
		return deviceRes.Location, nil
	}

	return
}

func (OrderPoints) MemberInfo(ctx context.Context, salesID, openID string) (data points.MemberMsg, err error) {
	if openID == "" {
		err = errorx.New("微信openid必传", -1)
		return
	}
	if salesID == "" {
		err = errorx.New("机器不能为空", -1)
		return
	}

	db := mysql.NewDB()
	WechatUserInfo, _ := dao.WechatUser{}.Detail(ctx, db, "", openID)
	if WechatUserInfo == nil || WechatUserInfo.Phone == "" {
		err = errorx.New("当前用户未注册", 100099)
		return
	}
	RobotLocationInfo, err1 := OrderPoints{}.GetRobotLocationInfo(ctx, db, salesID)
	if err1 != nil {
		err = err1
		return
	}
	if RobotLocationInfo.PointsId == "" {
		err = errorx.New("积分类型错误", -1)
		return
	}
	if _, ok := define.PointsType[RobotLocationInfo.PointsId]; !ok {
		err = errorx.New("积分类型错误", -1)
		return
	}
	// 获取正弘系统用户信息
	data, err = points.NewPoints(RobotLocationInfo.PointsId).GetMemberInfo(ctx, db, salesID, WechatUserInfo.Phone, openID)
	if data.ID == "" || err != nil {
		err = errorx.New("当前用户未注册", 100099)
		return
	}
	return
}

// 用户注册
func (OrderPoints) MemberRegist(ctx context.Context, db *gorm.DB, salesID, openID, phone, code, name string, gender int, birthday, IDCard, HeadImg, ProvinceId, CityId, AreaId, Address string) (err error) {
	if openID == "" {
		err = errorx.New("微信openid必传", -1)
		return
	}
	if salesID == "" {
		err = errorx.New("机器不能为空", -1)
		return
	}
	if phone == "" {
		err = errorx.New("联系电话不能为空", -1)
		return
	}
	match, matchErr := regexp.MatchString(`^(?:(?:\+|00)86)?1[3-9]\d{9}$`, phone)
	if matchErr != nil || !match {
		err = errorx.New("联系电话验证失败", -1)
		return
	}
	if code == "" {
		err = errorx.New("验证码不能为空", -1)
		return
	}

	WechatUserInfo, _ := dao.WechatUser{}.Detail(ctx, db, "", openID)
	if HeadImg == "" {
		HeadImg = WechatUserInfo.Image
	}

	// redis验证码校验
	boolean, err1 := helper.CheckSMSCode(redis.NewDB(), phone, code)
	if !boolean || err1 != nil {
		err = errorx.New("验证码校验错误", -1)
		return
	}
	RobotLocationInfo, err1 := OrderPoints{}.GetRobotLocationInfo(ctx, db, salesID)
	if err1 != nil {
		err = err1
		return
	}
	if RobotLocationInfo.PointsId == "" {
		err = errorx.New("积分类型错误", -1)
		return
	}
	if _, ok := define.PointsType[RobotLocationInfo.PointsId]; !ok {
		err = errorx.New("积分类型错误", -1)
		return
	}
	// 拿到手机号，请求正弘系统用户信息
	data, err1 := points.NewPoints(RobotLocationInfo.PointsId).GetMemberInfo(ctx, db, salesID, phone, openID)
	if data.ID != "" && err1 == nil { // 正弘已存在
		db.Model(&models.MaWechatUser{}).
			Where("open_id = ?", openID).
			UpdateColumn("phone", phone)
		err = err1
		return
	}

	// phoneInUse, _ := dao.WechatUser{}.Detail(ctx, db, phone, "")
	// if phoneInUse != nil && phoneInUse.Phone != "" {
	// err = errorx.New("手机号已被占用", -1)
	// return
	// }

	err = points.NewPoints(RobotLocationInfo.PointsId).MemberRegist(ctx, db, salesID, RobotLocationInfo.PointsMallId, phone, name, gender, birthday, IDCard, openID, HeadImg, ProvinceId, CityId, AreaId, Address)

	// 绑定微信openid和手机号
	if openID != "" && phone != "" {
		db.Model(&models.MaWechatUser{}).
			Where("open_id = ?", openID).
			UpdateColumn("phone", phone)
	}
	return err
}

// GetCartGoods 获取订单购物车商品信息
func (OrderPoints) GetCartGoods(ctx context.Context, orderID string) (totalAmount float64, CartGoods []CartGoodsStruct, err error) {

	logx.Info(context.Background(), "GetCartGoods", logx.Any("orderID", orderID))
	if orderID == "" {
		err = errorx.New("订单号不能为空", -1)
		return
	}
	orderID = strings.TrimSuffix(orderID, "P") // 去掉后缀P

	// 订单是否存在
	OrderList := []models.MaOrder{}
	var count int64
	db := mysql.NewDB()
	db.Model(&models.MaOrder{}).
		Where("out_trade_no = ?", orderID).
		Find(&OrderList).
		Count(&count)
	if count == 0 {
		err = errorx.New("订单不存在", -1)
		return
	}

	var GoodsIDList []string
	var TotalCountData []schema.OrderGoodsDetail
	var RobotNames []string
	for _, v := range OrderList {
		if v.End == 1 {
			err = errorx.New("订单已关闭，请重新购买", -1)
			return
		}
		// 订单信息返回
		CountData := common.Order{}.CountDataOldToNew(v.CountData)
		for _, goods := range CountData {
			if !lo.Contains[string](GoodsIDList, goods.GoodsID) {
				GoodsIDList = append(GoodsIDList, goods.GoodsID)
			}
			totalAmount += goods.Univalent
		}
		TotalCountData = append(TotalCountData, CountData...)
		RobotNames = append(RobotNames, v.RobotName)
	}

	// 获取商品信息
	var GoodsList []OrderGoodsInfo
	db.Model(&models.MaGoodsInfo{}).
		Where("goods_id in (?)", GoodsIDList).
		Select("goods_id, goods_type, goods_image, points, points_support, deduction_limit").
		Find(&GoodsList)
	GoodsIDMap := make(map[string]OrderGoodsInfo)
	for _, v := range GoodsList {
		GoodsIDMap[v.GoodsID] = v
	}

	CartGoods = []CartGoodsStruct{}
	for i, v := range TotalCountData {
		item := CartGoodsStruct{
			ID:           v.ID,
			ClassID:      v.ClassID,
			GoodsName:    v.GoodsName,
			ContainerNum: v.ContainerNum,
			Univalent:    v.Univalent,
			RobotName:    RobotNames[i],
		}
		item.GoodsID = v.GoodsID // 商品ID
		if _, ok := GoodsIDMap[v.GoodsID]; ok {
			item.GoodsType = GoodsIDMap[v.GoodsID].GoodsType
			item.GoodsImage = GoodsIDMap[v.GoodsID].GoodsImage
			item.Points = GoodsIDMap[v.GoodsID].Points
			item.PointsSupport = GoodsIDMap[v.GoodsID].PointsSupport
			item.DeductionLimit = GoodsIDMap[v.GoodsID].DeductionLimit // 积分抵扣上限【元】
		}
		CartGoods = append(CartGoods, item)
	}
	return
}

// 订单支付
func (OrderPoints) WechatJspay(ctx context.Context, orderID, Openid string, Points float64, wapp int) (
	data wechat.JSAPIPayParams, err error,
) {
	logx.Error(ctx, "OrderPoints WechatJspay Entry", logx.Any("orderID", orderID))
	logx.Error(ctx, "OrderPoints WechatJspay Entry", logx.Any("Points", Points))

	if orderID == "" {
		err = errorx.New("订单号不能为空", -1)
		return
	}
	orderID = strings.TrimSuffix(orderID, "P")
	if Points < 0 {
		err = errorx.New("积分异常", -1)
		return
	}
	var OrderInfo models.MaOrder
	var count int64

	// 订单信息
	db := mysql.NewDB()
	db.Model(&models.MaOrder{}).
		Where("out_trade_no = ?", orderID).
		Take(&OrderInfo).
		Count(&count)
	if count == 0 {
		err = errorx.New("订单不存在", -1)
		return
	}
	if OrderInfo.End != 0 {
		err = errorx.New("订单已关闭", -1)
		return
	}

	// 0积分判断是否为0元购
	if Points == 0 {
		var goodsInfo models.MaGoodsInfo
		db.Model(&models.MaGoodsInfo{}).
			Where("goods_id = ?", OrderInfo.GoodsID).
			Take(&goodsInfo)
		if goodsInfo.GoodsType == 6 { // 0元购商品直接支付成功并返回
			var updateData = make(map[string]interface{})
			updateData["modify_time"] = time.Now()
			updateData["updated_at"] = time.Now().Unix()
			updateData["order_status"] = 2 // 支付成功
			db.Model(&models.MaOrder{}).
				Where("out_trade_no = ?", orderID).
				Updates(&updateData)
			return
		}
	}

	// 机器对接的积分系统信息
	RobotLocationInfo, err1 := OrderPoints{}.GetRobotLocationInfo(ctx, db, OrderInfo.SalesID)
	if err1 != nil {
		return data, err1
	}
	// 小程序来源，可能未配置积分
	if wapp != 1 && RobotLocationInfo.PointsId == "" {
		return data, errorx.New("积分类型错误", -1)
	}
	if wapp != 1 || (wapp == 1 && RobotLocationInfo.PointsId == "5") {
		if _, ok := define.PointsType[RobotLocationInfo.PointsId]; !ok {
			return data, errorx.New("积分类型错误", -1)
		}

		// 查询积分
		BalancePoints, balanceErr := points.NewPoints(RobotLocationInfo.PointsId).
			PointsQuery(ctx, OrderInfo.SalesID, Openid, RobotLocationInfo.PointsMallId)
		if balanceErr != nil {
			err = balanceErr
			return
		}

		if Points > BalancePoints {
			err = errorx.New("积分不足", -1)
			return
		}
	}

	//积分校验
	OrderTotalAmount, err1 := OrderPoints{}.CheckOrderPoints(ctx, OrderInfo.SalesID, orderID, Openid, Points, wapp, RobotLocationInfo)
	if err1 != nil {
		err = err1
		return
	}

	// 微信支付
	if OrderTotalAmount > 0 { // 实付金额 [允许0元购]
		paymentAmount := decimal.NewFromFloat(OrderTotalAmount).Mul(decimal.NewFromInt(100)).IntPart() //订单金额【分】

		// 微信支付初始化
		pay.WechatPay{}.V3ConfigInit("", "", "")
		jsapiRsp, err := pay.WechatPay{}.V3TransactionJsapi(ctx, orderID+"P", paymentAmount, Openid, "", wapp)
		if err != nil {
			logx.Error(ctx, "OrderPoints WechatJspay err", logx.Any("out_trade_no", OrderInfo.OutTradeNo), logx.Any("error", err))
			// 微信支付出错时，积分冲正
			OrderPointsInfo, _ := dao.OrderPoints{}.Detail(ctx, db, OrderInfo.OutTradeNo, 1)
			if OrderPointsInfo != nil && OrderPointsInfo.OutTradeNo == OrderInfo.OutTradeNo {
				orderRefundNo, _ := helper.UUID{}.String()
				logx.Error(ctx, "OrderPoints WechatJspay reverse", logx.Any("out_trade_no", OrderInfo.OutTradeNo))
				pointsID := OrderPointsInfo.PointsID
				OrderPointsInfo, _ := dao.OrderPoints{}.Detail(ctx, db, orderID, 2)
				if OrderPointsInfo == nil || OrderPointsInfo.ID == "" { // 防多次回正
					pointsIntf := points.NewPoints(pointsID)
					if pointsIntf != nil {
						tradeErr := pointsIntf.PointsReverse(
							ctx,
							db,
							OrderPointsInfo.SalesID,        // 1. 机器识别码
							OrderPointsInfo.OpenID,         // 2. OpenID
							orderRefundNo,                  // 3. 退款单号
							OrderPointsInfo.OutTradeNo,     // 4. 订单号
							-OrderPointsInfo.Points,        // 5. 需要退款的金额（正数）
							RobotLocationInfo.PointsMallId, // 6. 积分对接的商场ID
						)
						if tradeErr != nil {
							logx.Error(ctx, "积分取消支付错误", logx.Any("out_trade_no", OrderInfo.OutTradeNo), logx.Any("error", tradeErr))
						} else {
							// 订单积分冲正记录
							dao.OrderPoints{}.Create(ctx, db, OrderPointsInfo.SalesID, OrderPointsInfo.OutTradeNo,
								OrderPointsInfo.OpenID, 2, OrderPointsInfo.PointsID, -OrderPointsInfo.Points)
						}
					}
				}
			}
		}
		return *jsapiRsp, err
	} else {
		// 小程序发货信息录入

		mp, err1 := pkg.MiniProgram{}.New()
		if err1 != nil {
			return
		}
		timeNow := time.Now()
		var shipping = &miniOrder.UploadShippingInfoRequest{
			OrderKey: &miniOrder.ShippingOrderKey{
				OrderNumberType: 1, // 商户侧单号
				Mchid:           config.Config.WechatV3Config.MchID,
				OutTradeNo:      orderID,
			},
			LogisticsType: miniOrder.LogisticsTypeSelfPickup,     // 用户自提
			DeliveryMode:  miniOrder.DeliveryModeUnifiedDelivery, // 同一发货
			ShippingList: []*miniOrder.ShippingInfo{
				{
					ItemDesc: "大道售卖商品",
				},
			},
			UploadTime: &timeNow,
			Payer: &miniOrder.ShippingPayer{
				Openid: Openid,
			},
		}
		err1 = mp.GetShipping().UploadShippingInfo(shipping)
		logx.Info(context.Background(), "WechatPay", logx.Any("upload_shipping_info", err1))

	}
	return
}

// CheckOrderPoints 积分检查是否不足
// ActualAmount		实付金额
func (OrderPoints) CheckOrderPoints(ctx context.Context, salesID, orderID, Openid string, MemberPoints float64,
	wapp int, RobotLocationInfo *devicec.Location) (ActualAmount float64, err error) {
	db := mysql.NewDB()
	var PointsGoods int                          // 积分商品[1是2否]
	var TotalPoints float64                      // 订单需耗费的积分
	var TotalDeductionLimit float64              // 抵额上限
	var DeductionAmount float64                  // 消耗积分
	var PointsAmount float64                     // 额购积分
	PointsValue := RobotLocationInfo.PointsValue // 积分价值
	logx.Error(ctx, "CheckOrder CheckOrderPoints", logx.Any("MemberPoints", fmt.Sprint(MemberPoints)))
	logx.Error(ctx, "CheckOrder CheckOrderPoints", logx.Any("PointsValue", fmt.Sprint(PointsValue)))
	logx.Error(ctx, "CheckOrder CheckOrderPoints", logx.Any("orderID", orderID))

	_, CartGoodsList, err := OrderPoints{}.GetCartGoods(ctx, orderID)
	for _, v := range CartGoodsList {
		if v.GoodsType == 4 {
			if PointsGoods != 0 && PointsGoods != 1 {
				err = errorx.New("积分商品与普通商品不能同时购买", -1)
				return
			}
			PointsGoods = 1 // 积分商品
		} else {
			if PointsGoods != 0 && PointsGoods != 2 {
				err = errorx.New("积分商品与普通商品不能同时购买", -1)
				return
			}
			PointsGoods = 2 // 普通商品
		}
		if v.Univalent < 0 {
			err = errorx.New("订单金额异常", -1)
			return
		}
		if v.GoodsType != 4 {
			TotalDeductionLimit += v.DeductionLimit // 抵额上限
		}
	}
	logx.Error(ctx, "CheckOrder CheckOrderPoints", logx.Any("TotalDeductionLimit", fmt.Sprint(TotalDeductionLimit)))
	logx.Error(ctx, "CheckOrder CheckOrderPoints", logx.Any("PointsGoods", PointsGoods))

	if PointsGoods == 1 { // 积分商品 => 额购积分 +　消耗积分
		var TotalDeductionPoints float64 // 可以现金抵扣的积分
		for _, v := range CartGoodsList {
			ActualAmount += v.Univalent
			if v.PointsSupport == 0 { // 现金抵扣关闭：需要固定金额 + 积分购买
				MemberPoints -= v.Points // 减去必须积分支付的积分
				TotalPoints += v.Points  // 必要支出的积分
			} else { // 现金抵扣开启：可以用现金抵扣积分
				TotalDeductionPoints += v.Points
			}
		}
		if MemberPoints < 0 { // 剩余积分不足
			err = errorx.New("实际可抵扣积分不足", -1)
			return
		}
		if TotalDeductionPoints >= 0 {
			if MemberPoints >= TotalDeductionPoints { // 剩余积分够用 => 全部用积分支付
				TotalPoints += TotalDeductionPoints
			} else { // 剩余积分不够用 => 有多少积分用多少积分，剩余的用现金支付
				//（待支付积分 - 剩余可用积分 = 抵扣的积分）/ 积分兑换率 = 额购积分
				TotalPoints += MemberPoints
				if PointsValue == 0 {
					err = errorx.New("积分配置错误，无法兑换", -1)
					return
				}
				PointsAmount = ((TotalDeductionPoints - MemberPoints) / float64(PointsValue)) // 额购积分
				ActualAmount += PointsAmount                                                  // 实付金额 + 额购积分
			}
			DeductionAmount = TotalPoints / float64(PointsValue) // 消耗积分
		}
		ActualAmount = common.Decimal(ActualAmount, 2)
	} else { // 普通商品 => 积分抵扣现金
		for _, v := range CartGoodsList {
			ActualAmount += v.Univalent
		}
		logx.Error(ctx, "CheckOrder CheckOrderPoints", logx.Any("普通商品 => 积分抵扣现金", ""))

		// 有积分就用积分抵扣
		TotalPoints = MemberPoints
		if RobotLocationInfo != nil && PointsAmount != 0 {

			if DeductionAmount > TotalDeductionLimit {
				err = errorx.New("积分抵扣达到抵额上限", -1)
				return
			}
		}
		DeductionAmount = MemberPoints / float64(PointsValue) // 抵扣金额
		ActualAmount -= DeductionAmount
		logx.Error(ctx, "CheckOrder CheckOrderPoints", logx.Any("DeductionAmount", fmt.Sprint(DeductionAmount)))

		// 订单金额验证
		ActualAmount = common.Decimal(ActualAmount, 2)
		if ActualAmount < 0 { // 注意订单现金抵扣时可能出现负数
			err = errorx.New("订单金额小于0", -1)
			return
		}
	}

	logx.Error(ctx, "CheckOrder CheckOrderPoints", logx.Any("ActualAmount", fmt.Sprint(ActualAmount)))
	// 现金为0时，最低支付1积分
	if ActualAmount == 0 && TotalPoints < 1 {
		err = errorx.New("最低需支付1积分", -1)
		return
	}

	logx.Error(ctx, "CheckOrder CheckOrderPoints", logx.Any("wapp", fmt.Sprint(wapp)))
	logx.Error(ctx, "CheckOrder CheckOrderPoints", logx.Any("RobotLocationInfo.PointsId", RobotLocationInfo.PointsId))
	// 非微信小程序或万象积分【5】时，修改订单信息
	// if wapp != 1 || (wapp == 1 && RobotLocationInfo.PointsId == "5") {
	if wapp != 1 {
		updateData := make(map[string]interface{})
		updateData["payment_id"] = 9                     // 9积分支付
		updateData["actual_amount"] = ActualAmount       // 实付金额
		updateData["deduction_amount"] = DeductionAmount // 抵扣金额
		updateData["discount_amount"] = DeductionAmount  // 抵扣金额
		updateData["points_amount"] = PointsAmount       // 额购积分
		updateData["points_value"] = PointsValue         // 积分价值
		updateData["modify_time"] = time.Now()
		updateData["updated_at"] = time.Now().Unix()
		updateData["deduction_limit"] = TotalDeductionLimit
		if ActualAmount > 0 { // 现金+积分
			db.Model(&models.MaOrder{}).
				Where("sales_id = ? and out_trade_no = ?", salesID, orderID).
				Updates(&updateData)
		} else { // 仅积分支付时修改订单状态为支付成功
			updateData["end_out_trade_no"] = orderID + "P"
			updateData["order_status"] = 2 // 支付成功
			db.Model(&models.MaOrder{}).
				Where("sales_id = ? and out_trade_no = ?", salesID, orderID).
				Updates(&updateData)
		}
	} else if wapp == 1 {
		updateData := make(map[string]interface{})
		updateData["actual_amount"] = ActualAmount       // 实付金额
		updateData["deduction_amount"] = DeductionAmount // 抵扣金额
		updateData["discount_amount"] = DeductionAmount  // 抵扣金额
		updateData["points_amount"] = PointsAmount       // 额购积分
		updateData["points_value"] = PointsValue         // 积分价值
		updateData["modify_time"] = time.Now()
		updateData["updated_at"] = time.Now().Unix()
		updateData["deduction_limit"] = TotalDeductionLimit
		if ActualAmount > 0 { // 现金+积分
			updateData["payment_id"] = 16 // 16积分支付+钱
			db.Model(&models.MaOrder{}).
				Where("sales_id = ? and out_trade_no = ?", salesID, orderID).
				Updates(&updateData)
		} else { // 仅积分支付时修改订单状态为支付成功
			updateData["payment_id"] = 17 // 17积分支付 0元
			updateData["end_out_trade_no"] = orderID + "P"
			updateData["order_status"] = 2 // 支付成功
			db.Model(&models.MaOrder{}).
				Where("sales_id = ? and out_trade_no = ?", salesID, orderID).
				Updates(&updateData)
		}
	}

	logx.Error(ctx, "CheckOrder CheckOrderPoints", logx.Any("TotalPoints", fmt.Sprint(TotalPoints)))
	// 积分扣减
	if TotalPoints > 0 { // 实付积分
		OrderPointsInfo, _ := dao.OrderPoints{}.Detail(ctx, db, orderID, 1)
		if OrderPointsInfo == nil || OrderPointsInfo.ID == "" { // 防多次支付

			if RobotLocationInfo.PointsId == "5" {

				tradeErr := points.NewPoints(RobotLocationInfo.PointsId).
					PointsConsume(ctx, db, salesID, Openid, orderID, TotalPoints, RobotLocationInfo.PointsMallId)
				if tradeErr != nil {
					err = tradeErr
					return
				}
			} else {

				tradeErr := points.NewPoints(RobotLocationInfo.PointsId).
					PointsConsume(ctx, db, salesID, Openid, orderID, -TotalPoints, RobotLocationInfo.PointsMallId)
				if tradeErr != nil {
					err = tradeErr
					return
				}
			}
			//订单积分记录
			dao.OrderPoints{}.Create(ctx, db, salesID, orderID, Openid, 1, RobotLocationInfo.PointsId, -TotalPoints)
		}
	}
	return
}

// 订单支付
func (OrderPoints) CheckOrder(ctx context.Context, orderID, Openid string, Points float64) (
	data wechat.JSAPIPayParams, err error,
) {

	logx.Error(ctx, "CheckOrder OrderPoints", logx.Any("orderID", orderID))
	logx.Error(ctx, "CheckOrder OrderPoints", logx.Any("Points", fmt.Sprint(Points)))
	if orderID == "" {
		err = errorx.New("订单号不能为空", -1)
		return
	}
	orderID = strings.TrimSuffix(orderID, "P")
	if Points < 0 {
		err = errorx.New("积分异常", -1)
		return
	}
	var OrderInfo models.MaOrder
	var count int64

	// 订单信息
	db := mysql.NewDB()
	db.Model(&models.MaOrder{}).
		Where("out_trade_no = ?", orderID).
		Take(&OrderInfo).
		Count(&count)

	logx.Error(ctx, "CheckOrder OrderPoints", logx.Any("count", fmt.Sprint(count)))
	if count == 0 {
		err = errorx.New("订单不存在", -1)
		return
	}
	if OrderInfo.End != 0 {
		err = errorx.New("订单已关闭", -1)
		return
	}

	// 0积分判断是否为0元购
	if Points == 0 {
		var goodsInfo models.MaGoodsInfo
		db.Model(&models.MaGoodsInfo{}).
			Where("goods_id = ?", OrderInfo.GoodsID).
			Take(&goodsInfo)
		if goodsInfo.GoodsType == 6 { // 0元购商品直接支付成功并返回
			var updateData = make(map[string]interface{})
			updateData["modify_time"] = time.Now()
			updateData["updated_at"] = time.Now().Unix()
			updateData["order_status"] = 2 // 支付成功
			db.Model(&models.MaOrder{}).
				Where("out_trade_no = ?", orderID).
				Updates(&updateData)
			return
		}
	}

	// 机器对接的积分系统信息
	RobotLocationInfo, err1 := OrderPoints{}.GetRobotLocationInfo(ctx, db, OrderInfo.SalesID)
	if err1 != nil {
		return data, err1
	}

	logx.Error(ctx, "CheckOrder OrderPoints", logx.Any("RobotLocationInfo", RobotLocationInfo.PointsId))
	// if RobotLocationInfo.PointsId == "5" {
	// 	if _, ok := define.PointsType[RobotLocationInfo.PointsId]; !ok {
	// 		return data, errorx.New("积分类型错误", -1)
	// 	}

	// 	// 查询积分
	// 	BalancePoints, balanceErr := points.NewPoints(RobotLocationInfo.PointsId).
	// 		PointsQuery(ctx, OrderInfo.SalesID, Openid, RobotLocationInfo.PointsMallId)
	// 	if balanceErr != nil {
	// 		err = balanceErr
	// 		return
	// 	}
	// 	logx.Error(ctx, "PointsConsume OrderPoints", logx.Any("BalancePoints", fmt.Sprint(BalancePoints)))

	// 	if Points > BalancePoints {
	// 		err = errorx.New("积分不足", -1)
	// 		return
	// 	}
	// }

	//积分校验
	OrderTotalAmount, err1 := OrderPoints{}.CheckOrderPoints(ctx, OrderInfo.SalesID, orderID, Openid, Points, 1, RobotLocationInfo)
	if err1 != nil {
		err = err1
		return
	}
	logx.Error(ctx, "PointsConsume OrderPoints", logx.Any("OrderTotalAmount", fmt.Sprint(OrderTotalAmount)))

	// 微信支付
	// if OrderTotalAmount > 0 { // 实付金额 [允许0元购]
	// 	paymentAmount := decimal.NewFromFloat(OrderTotalAmount).Mul(decimal.NewFromInt(100)).IntPart() //订单金额【分】

	// 	// 微信支付初始化
	// 	pay.WechatPay{}.V3ConfigInit("", "", "")
	// 	jsapiRsp, err := pay.WechatPay{}.V3TransactionJsapi(ctx, orderID+"P", paymentAmount, Openid, "", 1)
	// 	if err != nil {
	// 		logx.Error(ctx, "OrderPoints WechatJspay err", logx.Any("out_trade_no", OrderInfo.OutTradeNo), logx.Any("error", err))
	// 		// 微信支付出错时，积分冲正
	// 		OrderPointsInfo, _ := dao.OrderPoints{}.Detail(ctx, db, OrderInfo.OutTradeNo, 1)
	// 		if OrderPointsInfo != nil && OrderPointsInfo.OutTradeNo == OrderInfo.OutTradeNo {
	// 			orderRefundNo, _ := helper.UUID{}.String()
	// 			logx.Error(ctx, "OrderPoints WechatJspay reverse", logx.Any("out_trade_no", OrderInfo.OutTradeNo))
	// 			pointsID := OrderPointsInfo.PointsID
	// 			OrderPointsInfo, _ := dao.OrderPoints{}.Detail(ctx, db, orderID, 2)
	// 			if OrderPointsInfo == nil || OrderPointsInfo.ID == "" { // 防多次回正
	// 				pointsIntf := points.NewPoints(pointsID)
	// 				if pointsIntf != nil {
	// 					tradeErr := pointsIntf.PointsReverse(
	// 						ctx,
	// 						db,
	// 						OrderPointsInfo.SalesID,        // 1. 机器识别码
	// 						OrderPointsInfo.OpenID,         // 2. OpenID
	// 						orderRefundNo,                  // 3. 退款单号
	// 						OrderPointsInfo.OutTradeNo,     // 4. 订单号
	// 						-OrderPointsInfo.Points,        // 5. 需要退款的金额（正数）
	// 						RobotLocationInfo.PointsMallId, // 6. 积分对接的商场ID
	// 					)
	// 					if tradeErr != nil {
	// 						logx.Error(ctx, "积分取消支付错误", logx.Any("out_trade_no", OrderInfo.OutTradeNo), logx.Any("error", tradeErr))
	// 					} else {
	// 						// 订单积分冲正记录
	// 						dao.OrderPoints{}.Create(ctx, db, OrderPointsInfo.SalesID, OrderPointsInfo.OutTradeNo,
	// 							OrderPointsInfo.OpenID, 2, OrderPointsInfo.PointsID, -OrderPointsInfo.Points)
	// 					}
	// 				}
	// 			}
	// 		}
	// 	}
	// 	return *jsapiRsp, err
	// }
	return
}
